import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'
import { message } from 'antd'
import authService from '@/services/auth'
import { LoginData, UserInfo, CaptchaResponse } from '@/types/auth'

/**
 * 认证状态接口定义
 */
interface AuthState {
  isAuthenticated: boolean
  user: UserInfo | null
  token: string | null
  refreshToken: string | null
  loading: boolean
  error: string | null
  captcha: CaptchaResponse | null
}

/**
 * 初始状态定义
 * 注意：不在初始状态中直接读取localStorage，保持状态的纯净性
 */
const initialState: AuthState = {
  isAuthenticated: false,
  user: null,
  token: null,
  refreshToken: null,
  loading: false,
  error: null,
  captcha: null,
}

// ==================== 异步 Actions ====================

/**
 * 异步action：用户登录
 * @param loginData 登录数据
 */
export const login = createAsyncThunk(
  'auth/login',
  async (loginData: LoginData, { rejectWithValue }) => {
    try {
      const response = await authService.login(loginData)
      if (response.code === 200) {
        return response.data
      } else {
        return rejectWithValue(response.message)
      }
    } catch (error: any) {
      // 统一转为错误消息，避免 console 输出
      return rejectWithValue(error.message || '登录失败')
    }
  }
)

/**
 * 异步action：获取用户信息
 */
export const getUserInfo = createAsyncThunk(
  'auth/getUserInfo',
  async (_, { rejectWithValue }) => {
    try {
      const response = await authService.getUserInfo()
      if (response.code === 200) {
        return response.data
      } else {
        return rejectWithValue(response.message)
      }
    } catch (error: any) {
      return rejectWithValue(error.message || '获取用户信息失败')
    }
  }
)

/**
 * 异步action：用户登出
 */
export const logout = createAsyncThunk(
  'auth/logout',
  async (_, { rejectWithValue }) => {
    try {
      const response = await authService.logout()
      if (response.code === 200) {
        return response.data
      } else {
        return rejectWithValue(response.message)
      }
    } catch (error: any) {
      return rejectWithValue(error.message || '登出失败')
    }
  }
)

/**
 * 异步action：刷新令牌
 * @param refreshToken 刷新令牌
 */
export const refreshToken = createAsyncThunk(
  'auth/refreshToken',
  async (refreshToken: string, { rejectWithValue }) => {
    try {
      const response = await authService.refreshToken(refreshToken)
      if (response.code === 200) {
        return response.data
      } else {
        return rejectWithValue(response.message)
      }
    } catch (error: any) {
      return rejectWithValue(error.message || '刷新令牌失败')
    }
  }
)

/**
 * 异步action：修改密码
 * @param data 密码修改数据
 */
export const changePassword = createAsyncThunk(
  'auth/changePassword',
  async (data: { oldPassword: string; newPassword: string }, { rejectWithValue }) => {
    try {
      const response = await authService.changePassword(data)
      if (response.code === 200) {
        return response.data
      } else {
        return rejectWithValue(response.message)
      }
    } catch (error: any) {
      return rejectWithValue(error.message || '修改密码失败')
    }
  }
)

/**
 * 异步action：获取验证码
 */
export const getCaptcha = createAsyncThunk(
  'auth/getCaptcha',
  async (_, { rejectWithValue }) => {
    try {
      const response = await authService.getCaptcha()
      if (response.code === 200) {
        return response.data
      } else {
        return rejectWithValue(response.message)
      }
    } catch (error: any) {
      return rejectWithValue(error.message || '获取验证码失败')
    }
  }
)

/**
 * 异步action：检查认证状态
 */
export const checkAuth = createAsyncThunk(
  'auth/checkAuth',
  async (_, { rejectWithValue, getState }) => {
    const state = getState() as { auth: AuthState }
    const token = state.auth.token
    
    if (!token) {
      return rejectWithValue('No token found')
    }

    try {
      const response = await authService.getUserInfo()
      if (response.code === 200) {
        return { token, user: response.data }
      } else {
        return rejectWithValue(response.message)
      }
    } catch (error: any) {
      return rejectWithValue(error.message || '认证失败')
    }
  }
)

// ==================== Slice 定义 ====================

/**
 * 认证状态管理 Slice
 */

const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    /**
     * 清除错误信息
     */
    clearError: (state) => {
      state.error = null
    },
    
    /**
     * 设置token
     */
    setToken: (state, action: PayloadAction<string>) => {
      state.token = action.payload
      state.isAuthenticated = true
    },
    
    /**
     * 设置令牌对（token和refreshToken）
     */
    setTokens: (state, action: PayloadAction<{ token: string; refreshToken: string }>) => {
      const { token, refreshToken } = action.payload
      state.token = token
      state.refreshToken = refreshToken
      state.isAuthenticated = true
    },
    
    /**
     * 清除认证状态
     */
    clearAuth: (state) => {
      state.isAuthenticated = false
      state.user = null
      state.token = null
      state.refreshToken = null
      state.error = null
    },
    
    /**
     * 清除验证码
     */
    clearCaptcha: (state) => {
      state.captcha = null
    },
    
    /**
     * 重置认证状态
     */
    resetAuth: (state) => {
      state.isAuthenticated = false
      state.user = null
      state.token = null
      state.refreshToken = null
      state.error = null
      state.captcha = null
    },
  },
  extraReducers: (builder) => {
    builder
      // ==================== 登录相关 ====================
      .addCase(login.pending, (state) => {
        state.loading = true
        state.error = null
      })
      .addCase(login.fulfilled, (state, action) => {
        state.loading = false
        state.isAuthenticated = true
        state.token = action.payload.accessToken
        state.refreshToken = action.payload.refreshToken
        state.user = action.payload.userInfo || null
        state.error = null
        
        // 已移除开发环境下的登录成功与 Redux Persist 打印
        
        message.success('登录成功')
      })
      .addCase(login.rejected, (state, action) => {
        state.loading = false
        state.isAuthenticated = false
        state.error = action.payload as string
        message.error(action.payload as string)
      })
      
      // ==================== 获取用户信息 ====================
      .addCase(getUserInfo.pending, (state) => {
        state.loading = true
      })
      .addCase(getUserInfo.fulfilled, (state, action) => {
        state.loading = false
        state.isAuthenticated = true
        state.user = action.payload || null
        state.error = null
      })
      .addCase(getUserInfo.rejected, (state, action) => {
        state.loading = false
        state.isAuthenticated = false
        state.user = null
        state.token = null
        state.refreshToken = null
        state.error = action.payload as string
      })
      
      // ==================== 登出相关 ====================
      .addCase(logout.pending, (state) => {
        state.loading = true
      })
      .addCase(logout.fulfilled, (state) => {
        state.loading = false
        state.isAuthenticated = false
        state.user = null
        state.token = null
        state.refreshToken = null
        state.error = null
        message.success('登出成功')
      })
      .addCase(logout.rejected, (state, action) => {
        state.loading = false
        // 即使登出失败，也清除本地状态
        state.isAuthenticated = false
        state.user = null
        state.token = null
        state.refreshToken = null
        state.error = action.payload as string
        message.warning('登出时发生错误，但已清除本地状态')
      })
      
      // ==================== 刷新令牌 ====================
      .addCase(refreshToken.pending, (state) => {
        state.loading = true
      })
      .addCase(refreshToken.fulfilled, (state, action) => {
        state.loading = false
        state.token = action.payload.accessToken
        state.refreshToken = action.payload.refreshToken
        state.user = action.payload.userInfo || null
        state.error = null
        message.success('令牌刷新成功')
      })
      .addCase(refreshToken.rejected, (state, action) => {
        state.loading = false
        state.isAuthenticated = false
        state.user = null
        state.token = null
        state.refreshToken = null
        state.error = action.payload as string
        message.error('令牌刷新失败，请重新登录')
      })
      
      // ==================== 修改密码 ====================
      .addCase(changePassword.pending, (state) => {
        state.loading = true
        state.error = null
      })
      .addCase(changePassword.fulfilled, (state) => {
        state.loading = false
        message.success('密码修改成功')
      })
      .addCase(changePassword.rejected, (state, action) => {
        state.loading = false
        state.error = action.payload as string
        message.error(action.payload as string)
      })
      
      // ==================== 获取验证码 ====================
      .addCase(getCaptcha.pending, (state) => {
        state.loading = true
        state.error = null
      })
      .addCase(getCaptcha.fulfilled, (state, action) => {
        state.loading = false
        state.captcha = action.payload
      })
      .addCase(getCaptcha.rejected, (state, action) => {
        state.loading = false
        state.error = action.payload as string
        message.error(action.payload as string)
      })
      
      // ==================== 检查认证状态 ====================
      .addCase(checkAuth.pending, (state) => {
        state.loading = true
      })
      .addCase(checkAuth.fulfilled, (state, action) => {
        state.loading = false
        state.isAuthenticated = true
        state.token = action.payload.token
        state.user = action.payload.user
      })
      .addCase(checkAuth.rejected, (state) => {
        state.loading = false
        state.isAuthenticated = false
        state.user = null
        state.token = null
        state.refreshToken = null
      })
  },
})

// ==================== 导出 ====================

/**
 * 导出所有action creators
 */
export const { 
  clearError, 
  setToken, 
  setTokens,
  clearAuth,
  clearCaptcha, 
  resetAuth 
} = authSlice.actions

/**
 * 导出reducer
 */
export default authSlice.reducer

// ==================== 选择器 ====================

/**
 * 选择器：获取认证状态
 */
export const selectAuth = (state: { auth: AuthState }) => state.auth

/**
 * 选择器：获取用户信息
 */
export const selectUser = (state: { auth: AuthState }) => state.auth.user

/**
 * 选择器：获取认证状态
 */
export const selectIsAuthenticated = (state: { auth: AuthState }) => state.auth.isAuthenticated

/**
 * 选择器：获取加载状态
 */
export const selectAuthLoading = (state: { auth: AuthState }) => state.auth.loading

/**
 * 选择器：获取错误信息
 */
export const selectAuthError = (state: { auth: AuthState }) => state.auth.error

/**
 * 选择器：获取验证码
 */
export const selectCaptcha = (state: { auth: AuthState }) => state.auth.captcha